home *** CD-ROM | disk | FTP | other *** search
Java Source | 1997-06-19 | 19.9 KB | 826 lines |
- package symantec.itools.multimedia;
-
- import java.awt.*;
- import java.applet.Applet;
- import java.applet.AppletContext;
- import java.net.URL;
-
- /**
- * Scrolling text component. Forms a text banner that scrolls specified
- * text horizontally. The component allows multiple messages and links.
- *
- * @version 1.0, Feb 2, 1997
- * @author Symantec
- */
-
- // 02/02/97 RKM Checked it in
- // 02/07/97 RKM Fixed bug in paint where the font was noit being set up in the offscreen image (thanks Dave)
-
- public class ScrollingText
- extends Canvas
- implements Runnable
- {
- // Enums
-
- /**
- * Constant which indicates that the banner should scroll from right to left
- */
-
- public static final int SCROLL_LEFT = 0;
-
- /**
- * Constant which indicates that the banner should scroll from left to right
- */
-
- public static final int SCROLL_RIGHT = 1;
-
- // Property variables
-
- /**
- * Current scroll direction. Default value SCROLL_LEFT.
- */
- protected int scrollDirection;
-
- /**
- * Distance to scroll on each update. Distance is in pixels. Default value 10.
- */
- protected int scrollUnit; //the incremental scrolling distance in pixels
-
- /**
- * Controls the speed of the scroll. Default value 150.
- */
- protected int sleepTime; //controls the speed of the scroll
-
- /**
- * Color for highlighted text. Default value is red.
- */
-
- protected Color hiliteColor;
-
- /**
- * List of messages to scroll across the banner.
- */
- protected String[] messageList;
-
-
- /**
- * URL links which correspond with messages.
- */
- protected URL[] linkToList;
-
- /**
- * Location in browser to show linked HTML pages.
- * Valid values are "_self" to show in the current frame;
- * "_parent" show in the parent frame;
- * "_top" show in the topmost frame;
- * "_blank" show in a new unnamed top-level window;
- * name show in a new top-level window named name.
- */
- protected String frame;
-
- // Internal variables
-
- /**
- * If used in an applet, this is the applet's context.
- */
- protected AppletContext context;
-
- /**
- * Thread which runs the scrolling animation.
- */
- protected Thread scrollThread = null;
-
- /**
- * State of scrolling animation.
- */
- protected boolean suspended = false;
-
- /**
- * Current horizontal text position.
- */
- protected int textX;
-
- /**
- * Current vertical text position.
- */
- protected int textY;
-
- /**
- * Width of current message text.
- */
- protected int textWidth;
-
- /**
- * Height of current message text.
- */
- protected int textHeight;
-
-
- /**
- * Mouse over message text.
- */
- protected boolean isMouseOver = false;
-
- /**
- * Last mouse cursor position.
- */
- protected int lastMouseX,lastMouseY;
-
- /**
- * Status of mouse position.
- */
- protected boolean wasMouseOverText = false;
-
- /**
- * Previous status message.
- */
- protected String wasStatusMessage = "";
-
-
- /**
- * Current message text.
- */
- protected String currMessage;
-
- /**
- * Current URL link.
- */
- protected URL currLinkTo;
-
- /**
- * Index of current message text and URL
- */
- protected int currIndex;
-
- // Constructor
-
- /**
- * Construct default scrolling text banner.
- */
-
- public ScrollingText()
- {
- super();
-
- //Set defaults for properties
- scrollDirection = SCROLL_LEFT;
- scrollUnit = 10;
- sleepTime = 150;
- hiliteColor = Color.red;
- messageList = new String[0];
- linkToList = new URL[0];
- frame = null;
-
- //Init current message variables
- currMessage = "";
- currLinkTo = null;
- currIndex = -1;
- }
-
- // Getters/Setters
-
- /**
- * Set sleep time between scroll steps. This function controls
- * the speed of scrolling. A lower number indicates a faster speed.
- *
- * @param speed number of milliseconds to sleep between scroll steps. The smaller the
- * number the faster the scroll. Minimum value of 30.
- */
-
- public void setScrollInterval(int speed)
- {
- if (speed < 30)
- sleepTime = 30;
- else
- sleepTime = speed;
- }
-
- /**
- * Obtain the current scroll interval. This is the number of milliseconds
- * that the scroll thread will sleep between scroll steps.
- *
- * @return current scroll delay setting, in milliseconds
- */
-
- public int getScrollInterval()
- {
- return sleepTime;
- }
-
-
- /**
- * Specify the size of each scroll step.
- *
- * @param unit the number of pixels to move the text on each scroll step
- *
- */
-
- public void setScrollUnit(int unit)
- {
- if (unit < 1)
- scrollUnit = 1;
- else
- scrollUnit = unit;
- }
-
- /**
- * Obtain the current size of the scroll step.
- *
- * @return the number of pixels that text moves on each scroll step
- *
- */
-
- public int getScrollUnit()
- {
- return (scrollUnit < 0) ? -scrollUnit : scrollUnit;
- }
-
-
- /**
- * Specify the banner's current scroll direction.
- *
- * @param dir direction to scroll. Valid values are SCROLL_LEFT and SCROLL_RIGHT
- */
-
- public void setScrollDirection(int dir)
- {
- scrollDirection = dir;
- }
-
- /**
- * Obtain the current direction of scrolling.
- *
- * @return the current direction, either SCROLL_LEFT or SCROLL_RIGHT
- */
-
- public int getScrollDirection()
- {
- return scrollDirection;
- }
-
-
- /**
- * Set the highlight color for text. Text is highlighted in this color when the mouse cursor is over
- * it and it contains a non-null link.
- *
- * @param newHiliteColor color for highlighted text.
- */
-
- public void setHiliteColor(Color newHiliteColor)
- {
- hiliteColor = newHiliteColor;
- }
-
-
- /**
- * Obtain the current color for text highlighting
- *
- * @return current highlight color
- */
-
- public Color getHiliteColor()
- {
- return hiliteColor;
- }
-
-
- /**
- * Specify the current list of messages. These messages scroll sequentially
- * through the banner.
- *
- * @param list list of messages to display
- */
- public void setMessageList(String[] list)
- {
- messageList = list;
- updateCurrentMessage(false);
- }
-
-
- /**
- * Obtain the current list of messages.
- *
- * @return the current list of messages being displayed
- */
-
- public String[] getMessageList()
- {
- return messageList;
- }
-
-
- /**
- * Specify the list of URLs for message links.
- * Each link corresponds with a message in the message list.
- * If a message has no link, a null URL should be included for that message.
- *
- * @param list list of URL links
- */
-
- public void setLinkToList(URL[] list)
- {
- linkToList = list;
- updateCurrentMessage(false);
- }
-
-
- /**
- * Obtain the current set of URL links.
- *
- * @return list of URL links. Each URL corresponds to the message of the same index in the message list
- */
- public URL[] getLinkToList()
- {
- return linkToList;
- }
-
-
- /**
- * Specify the display location of linked pages. If the ScrollingText is in an applet this
- * method determines where the linked pages are displayed.
- *
- * @param f where to display the linked documents.
- * Valid values are "_self" to show in the current frame;
- * "_parent" show in the parent frame;
- * "_top" show in the topmost frame;
- * "_blank" show in a new unnamed top-level window;
- * <name> show in a new top-level window named name
- */
- public void setFrame(String f)
- {
- frame = f;
- }
-
-
- /**
- * Obtain the display location of linked pages. If the ScrollingText is in an applet this
- * method returns where the linked pages are displayed.
- *
- * @return Place to display the linked documents.
- * Valid values are "_self" to show in the current frame;
- * "_parent" show in the parent frame;
- * "_top" show in the topmost frame;
- * "_blank" show in a new unnamed top-level window;
- * <name> show in a new top-level window named name
- */
- public String getFrame()
- {
- return frame;
- }
-
- // Overridden methods
-
-
- /**
- * Tells this component that it has been added to a container.
- * This is a standard Java AWT method which gets called by the AWT when
- * this component is added to a container. Typically, it is used to
- * create this component's peer.
- *
- * It has been overridden here to start the scrolling text thread.
- *
- * @see #removeNotify
- */
- public synchronized void addNotify()
- {
- super.addNotify();
- scrollThread = new Thread(this);
- scrollThread.setPriority(Thread.MIN_PRIORITY);
- scrollThread.start();
- }
-
- /**
- * Tells this component that it is being removed from a container.
- * This is a standard Java AWT method which gets called by the AWT when
- * this component is removed from a container. Typically, it is used to
- * destroy the peers of this component and all its subcomponents.
- *
- * It has been overridden here to stop the scrolling text thread.
- *
- * @see #addNotify
- */
- public synchronized void removeNotify() {
- if (scrollThread != null) {
- scrollThread.stop();
- scrollThread = null;
- }
- super.removeNotify();
- }
-
-
- /**
- * Resumes the animation of the scrolling text.
- */
- public void startScrollingText() {
- suspended = false;
- show();
- }
-
-
- /**
- * Suspends the animation of the scrolling text.
- */
- public void stopScrollingText() {
- suspended = true;
- }
-
-
- /**
- * Makes this component visible.
- * This is a standard Java AWT method which gets called to show this
- * component. If this component was invisible due to a previous hide()
- * call it make this component visible again.
- *
- * @see #hide
- */
- public synchronized void show() {
- super.show();
- if (isVisible()) {
- if (scrollThread != null) {
- scrollThread.setPriority(Thread.MAX_PRIORITY);
- scrollThread.resume();
- }
- }
- }
-
-
- /**
- * Makes this component invisible.
- * This is a standard Java AWT method which gets called to hide
- * this component. A hidden component cannot be seen by the user nor
- * does it take up space in its container, but it does continue to
- * exist.
- *
- * @see #show
- */
- public synchronized void hide() {
- super.hide();
- if (!isVisible()) {
- if (scrollThread != null)
- scrollThread.suspend();
- }
- }
-
-
- /**
- * ScrollingText thread body. This method is called by the Java virtual
- * machine to when this thread starts.
- */
- public void run()
- {
- createTextParams();
- while (true)
- {
- if (!suspended)
- {
- nextPos();
- try
- {
- Thread.sleep(sleepTime);
- }
- catch(Exception e)
- {
- }
- }
- }
- }
-
-
- /**
- * Move to next message in message list. Not usually called directly.
- *
- * @param next if true, move to next message; otherwise reset message with current index
- */
- public void updateCurrentMessage(boolean next)
- {
- //Increase currIndex, try to get message out
- try
- {
- if (next)
- currIndex++;
- currMessage = messageList[currIndex];
- }
- catch(ArrayIndexOutOfBoundsException e)
- {
- //Index is out of range, reset to zero
- try
- {
- currIndex = 0;
- currMessage = messageList[0];
- }
- catch(ArrayIndexOutOfBoundsException e2)
- {
- //No index is valid at this point
- currMessage = "";
- }
- }
-
- // Get current link to, if one is there
- try
- {
- currLinkTo = linkToList[currIndex];
- }
- catch(ArrayIndexOutOfBoundsException e)
- {
- currLinkTo = null;
- }
-
- createTextParams();
- }
-
-
- /**
- * Increment scroll step. Moves to next message as needed. Not usually called directly.
- */
- public synchronized void nextPos()
- {
- Dimension dim = size();
- if (scrollDirection == SCROLL_LEFT)
- {
- textX -= scrollUnit;
- if ((textX + textWidth) < 0)
- {
- updateCurrentMessage(true);
- textX = dim.width;
- }
- }
- else
- {
- textX += scrollUnit;
- if (textX > dim.width)
- {
- updateCurrentMessage(true);
- textX = -textWidth;
- }
- }
-
- repaint();
- }
-
-
- /**
- * Setup metrics information for current message. Sets textX, textY, textHeight and textWidth.
- */
- protected void createTextParams()
- {
- Font f = getFont();
- if (f != null)
- {
- FontMetrics fm = getFontMetrics(f);
- textHeight = fm.getHeight();
-
- Dimension dim = size();
- textX = dim.width;
- textY = ((dim.height - textHeight) >> 1) + fm.getAscent();
- textWidth = fm.stringWidth(currMessage);
- }
- }
-
- /**
- * Handles redrawing of this component on the screen.
- * This is a standard Java AWT method which gets called by the Java
- * AWT (repaint()) to handle repainting this component on the screen.
- * The graphics context clipping region is set to the bounding rectangle
- * of this component and its <0,0> coordinate is this component's
- * top-left corner.
- * Typically this method paints the background color to clear the
- * component's drawing space, sets graphics context to be the foreground
- * color, and then calls paint() to draw the component.
- *
- * It is overridden here to reduce flicker by eliminating the uneeded
- * clearing of the background.
- *
- * @param g the graphics context
- * @see java.awt.Component#repaint
- * @see #paint
- */
- public void update(Graphics g) {
- //Override update to avoid flashing of text area
- paint(g);
- }
-
-
- /**
- * Determines if the given point is over the current text.
- *
- * @param x horizontal location of point
- * @param y vertical location of point
- *
- * @return true if given point is over the current text
- */
- protected boolean isMouseOverText(int x, int y)
- {
- if (isMouseOver)
- {
- if (x >= textX && x <= textX + textWidth)
- {
- if (y >= textY - textHeight && y <= textY)
- return true;
- }
- }
-
- return false;
- }
-
-
- /**
- * Paints this component using the given graphics context.
- * This is a standard Java AWT method which typically gets called
- * by the AWT to handle painting this component. It paints this component
- * using the given graphics context. The graphics context clipping region
- * is set to the bounding rectangle of this component and its <0,0>
- * coordinate is this component's top-left corner.
- *
- * @param g the graphics context used for painting
- * @see java.awt.Component#repaint
- * @see #update
- */
- public void paint(Graphics g)
- {
- //Create an image the size of the component
- Dimension dim = size();
- Image textImage = createImage(dim.width, dim.height);
- Graphics textGC = textImage.getGraphics();
-
- //Draw the background color
- textGC.setColor(getBackground());
- textGC.fillRect(0, 0, dim.width, dim.height);
-
- textGC.setFont(getFont());
-
- //Determine where the mouse is
- boolean mouseOverText = isMouseOverText(lastMouseX, lastMouseY);
- if (mouseOverText != wasMouseOverText)
- {
- if (context != null)
- {
- String newStatusMessage;
- if (wasMouseOverText || currLinkTo == null)
- newStatusMessage = "";
- else
- newStatusMessage = currLinkTo.toString();
-
- //Update status, only if something has changed
- if (!wasStatusMessage.equals(newStatusMessage))
- {
- context.showStatus(newStatusMessage);
- wasStatusMessage = newStatusMessage;
- }
- }
-
- wasMouseOverText = mouseOverText;
- }
-
- //Draw the text
- textGC.setColor(mouseOverText && currLinkTo != null ? hiliteColor : getForeground());
- textGC.drawString(currMessage, textX, textY);
- g.drawImage(textImage, 0, 0, this);
-
- //Don't wait for the gc, we know textImage is trash
- textImage.flush();
- }
-
-
- /**
- * Processes MOUSE_MOVE events.
- * This is a standard Java AWT method which gets called by the AWT
- * method handleEvent() in response to receiving a MOUSE_MOVE
- * event. These events occur when the mouse is moved around inside this
- * component while the button is NOT pressed.
- *
- * @param evt the event
- * @param x the component-relative horizontal coordinate of the mouse
- * @param y the component-relative vertical coordinate of the mouse
- *
- * @return always true since the event was handled
- *
- * @see java.awt.Component#mouseDrag
- * @see java.awt.Component#handleEvent
- */
- public boolean mouseMove(Event evt, int x, int y) {
- isMouseOver = true;
-
- //Use this later to determine if the mouse is over the text
- lastMouseX = x;
- lastMouseY = y;
-
- return true;
- }
-
-
- /**
- * Processes MOUSE_EXIT events.
- * This is a standard Java AWT method which gets called by the AWT
- * method handleEvent() in response to receiving a MOUSE_EXIT
- * event. These events occur when the mouse first leaves this
- * component.
- *
- * @param e the event
- * @param x the component-relative horizontal coordinate of the mouse
- * @param y the component-relative vertical coordinate of the mouse
- *
- * @return always true since the event was handled
- *
- * @see java.awt.Component#mouseEnter
- * @see java.awt.Component#handleEvent
- */
- public boolean mouseExit(Event evt, int x, int y) {
- isMouseOver = false;
-
- return true;
- }
-
-
- /**
- * Processes MOUSE_DOWN events.
- * This is a standard Java AWT method which gets called by the AWT
- * method handleEvent() in response to receiving a MOUSE_DOWN
- * event. These events occur when the mouse button is pressed while
- * inside this component.
- *
- * @param e the event
- * @param x the component-relative horizontal coordinate of the mouse
- * @param y the component-relative vertical coordinate of the mouse
- *
- * @return always true since the event was handled
- *
- * @see java.awt.Component#mouseUp
- * @see java.awt.Component#handleEvent
- */
- public boolean mouseDown(Event evt, int x, int y) {
- //If we have somewhere to go and the mouse is over the text
- if (currLinkTo != null && isMouseOverText(x, y))
- {
- if (context != null)
- {
- if (frame == null || frame.length() == 0)
- context.showDocument(currLinkTo);
- else
- context.showDocument(currLinkTo,frame);
- }
- }
-
- return true;
- }
-
-
- /**
- * Ensures that this component is laid out properly, as needed.
- * This is a standard Java AWT method which gets called by the AWT to
- * make sure this component and its subcomponents have a valid layout.
- * If this component was made invalid with a call to invalidate(), then
- * it is laid out again.
- *
- * It is overridden here to also find the containing applet at validation time.
- *
- * @see java.awt.Component#invalidate
- */
- public void validate()
- {
- // On validation, try to find the containing applet. If we can find
- // it, we don't bother doing the link...
- Container c = getParent();
-
- while (c != null)
- {
- if (c instanceof Applet)
- {
- setAppletContext(((Applet) c).getAppletContext());
- break;
- }
-
- c = c.getParent();
- }
- }
-
-
- /**
- * Specify the current applet context.
- *
- * @param c new applet context
- */
- protected void setAppletContext(AppletContext c)
- {
- context = c;
- }
-
-
- /**
- * Moves and/or resizes this component.
- * This is a standard Java AWT method which gets called to move and/or
- * resize this component. Components that are in containers with layout
- * managers should not call this method, but rely on the layout manager
- * instead.
- *
- * @param x horizontal position in the parent's coordinate space
- * @param y vertical position in the parent's coordinate space
- * @param width the new width
- * @param height the new height
- */
- public synchronized void reshape(int x, int y, int width, int height) {
- super.reshape(x,y,width,height);
-
- createTextParams();
- }
- }
-